function varargout = ICAcleanerGUI(varargin) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Performs ICA decomposition and component removal. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Copyright (C) 2013-2014, Michael J. Cheung % % This file is a part of the MEG & PLS Pipeline (MEGPLS). For more % details, see the documentation included with the software package. % % MEGPLS is free software: you can redistribute it and/or modify it under % the terms of the GNU General Public License version 2 as published by % the Free Software Foundation. This program is distributed in the hope % that it will be useful, but WITHOUT ANY WARRANTY; without even the % implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. % See the GNU General Public License for more details. % % You should have received a copy of the GNU General Public License along % with this program. If not, you can download the license here: % . % Last Modified by GUIDE v2.5 31-Jul-2014 15:45:56 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @ICAcleanerGUI_OpeningFcn, ... 'gui_OutputFcn', @ICAcleanerGUI_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT %--- Executes just before ICAcleanerGUI is made visible. ---% %-----------------------------------------------------% function ICAcleanerGUI_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to ICAcleanerGUI (see VARARGIN) % Choose default command line output for ICAcleanerGUI handles.output = hObject; % Make sure toolbox paths are added: [PipelineDir, ~, ~] = fileparts(which('ICAcleanerGUI.m')); handles.PipelineDir = PipelineDir; addpath(genpath(PipelineDir)); rmpath([PipelineDir,'/DEFAULT_SETTINGS']); % Make sure its calling from DataID rmpath([PipelineDir,'/TEMPORARY_FIXES']); % Make sure its calling from FT toolbox CheckToolboxPaths(PipelineDir); if exist('ErrorLog_ICAcleaner.txt', 'file') system('rm ErrorLog_ICAcleaner.txt'); end % Initializes variables being displayed: handles.paths.Rootpath = []; handles.paths.DataID = []; handles.name.DataID = []; handles.name.GroupID = []; handles.name.SubjID = []; handles.name.CondID = []; handles.paths.InputPreprocMEG = []; handles.paths.ICAunmixing = []; handles.paths.ICAcomponents = []; handles.paths.ICAcleanData = []; handles.gui.InpOutStatus = []; handles.gui.RmvCompStatus = []; handles.gui.SelectComps = []; handles.FTcfg = []; % Save handles: guidata(hObject, handles); % UIWAIT makes ICAcleanerGUI wait for user response (see UIRESUME) % uiwait(handles.figure1); %--- Outputs from this function are returned to the command line. ---% %--------------------------------------------------------------------% function varargout = ICAcleanerGUI_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; %===================================% % FUNCTIONS FOR SELECTING ROOTPATH: % %===================================% %--- Executes on button press in ButtonSetRootpath. ---% %------------------------------------------------------% function ButtonSetRootpath_Callback(hObject, eventdata, handles) if ~isempty(handles.name.DataID) prompt = {'WARNING:'; ''; 'Changing root directory will clear all current settings!'; ''; 'Do you wish to continue?'}; ChangeDir = questdlg(prompt, 'WARNING:', 'YES', 'NO', 'NO'); if strcmp(ChangeDir, 'NO') return; end end % Select and set Rootpath: SelectedPath = uigetdir; if SelectedPath == 0 return % If user cancels end handles.paths.Rootpath = SelectedPath; set(handles.TextboxRootpath, 'String', handles.paths.Rootpath); % Start Waitbox: WaitBox = StartWaitBox('SETTING ROOT DIRECTORY:'); % Reset DataID: handles.name.DataID = []; handles.paths.DataID = []; set(handles.TextboxDataID, 'String', 'Not Selected.'); % Reset settings & GUI panels: handles = ResetGroupIDSettings (handles); handles = ResetSubjIDSettings (handles); handles = ResetCondIDSettings (handles); handles = ResetStatusSettings (handles); handles.paths.InputPreprocMEG = []; handles.paths.ICAcomponents = []; handles.paths.ICAunmixing = []; handles.paths.ICAcleanData = []; handles.gui.SelectComps = []; % Update settings & GUI panels (to enable/disable): % Note: Don't redetect or compile paths yet since no DataID yet. handles = UpdateGroupIDSettings (handles); handles = UpdateSubjIDSettings (handles); handles = UpdateCondIDSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); close(WaitBox); %--- Textbox to display selected Rootpath: ---% %---------------------------------------------% function TextboxRootpath_Callback(hObject, eventdata, handles) EnteredText = get(handles.TextboxRootpath, 'String'); if ~isequal(EnteredText, handles.paths.Rootpath) set(handles.TextboxRootpath, 'String', handles.paths.Rootpath); msgbox('Note: Use button to change Rootpath.') end %=========================================% % FUNCTIONS FOR READING & LOADING DATAID: % %=========================================% %--- Textbox to display current DataID: ---% %------------------------------------------% function TextboxDataID_Callback(hObject, eventdata, handles) EnteredText = get(handles.TextboxDataID, 'String'); if ~isequal(EnteredText, handles.name.DataID) set(handles.TextboxDataID, 'String', handles.name.DataID); msgbox('Note: Use button to change DataID.') end %--- Executes on button press in ButtonLoadDataID. ---% %-----------------------------------------------------% function ButtonLoadDataID_Callback(hObject, eventdata, handles) if isempty(handles.paths.Rootpath) msgbox('Warning: Select target directory first.', 'Warning:'); return; end % Get DataID folders in current rootpath: DetectedFolders = dir([handles.paths.Rootpath,'/DataID_*']); RemoveIndex = []; for d = 1:length(DetectedFolders) if DetectedFolders(d).isdir ~= 1 RemoveIndex = [RemoveIndex, d]; % Get unwanted indices end end DetectedFolders(RemoveIndex) = []; if isempty(DetectedFolders) msgbox('Error: No DataID folders detected inside target directory.', 'Error:'); return; end % List DataID folders for selection: DetectedFolders = {DetectedFolders.name}; SelectedIndex = listdlg('PromptString', 'Select DataID to load:',... 'ListSize', [300, 300], 'SelectionMode', 'single', 'ListString', DetectedFolders); if isempty(SelectedIndex) % If user cancels. return; end SelectedDataID = DetectedFolders{SelectedIndex}; SelectedDataID(1:7) = []; % Remove "DataID_" prefix to get DataID tag. FullpathDataID = [handles.paths.Rootpath,'/DataID_',SelectedDataID]; % Check or create settings .m file for ICA: if ~exist([FullpathDataID,'/SETTINGS'], 'dir') success = mkdir([FullpathDataID,'/SETTINGS']); if success == 0 message = {'ERROR:'; ''; 'Failed to create SETTINGS folder in selected DataID.'; 'Ensure you have proper folder and file permissions.'}; msgbox(message, 'ERROR:') return; end end DefaultSettingsFile = [handles.PipelineDir,'/DEFAULT_SETTINGS/Settings_ICA.m']; NewSettingsFile = [FullpathDataID,'/SETTINGS/Settings_ICA.m']; if ~exist(NewSettingsFile, 'file') status = copyfile(DefaultSettingsFile, NewSettingsFile, 'f'); if status == 0 message = {'ERROR:'; ''; 'Failed to create ICA advanced settings .m file for selected DataID.'; 'Could not copy file from [MEG]PLS "DEFAULT_SETTINGS" directory.'; 'Check for proper folder and file permissions.'}; msgbox(message, 'ERROR:') return; end end % Set as current DataID: handles.name.DataID = SelectedDataID; handles.paths.DataID = FullpathDataID; % Reset settings & GUI panels: handles = ResetGroupIDSettings (handles); handles = ResetSubjIDSettings (handles); handles = ResetCondIDSettings (handles); handles = ResetStatusSettings (handles); handles.paths.InputPreprocMEG = []; handles.paths.ICAcomponents = []; handles.paths.ICAunmixing = []; handles.paths.ICAcleanData = []; handles.gui.SelectComps = []; % Compile Group, Subj, and CondIDs for DataID: % Note: Also initializes Group, Subj, CondIDs. handles = DetectGroupSubjCond(handles); if isempty(handles.name.GroupID) msgbox('ERROR: No GroupID folders detected for selected DataID.') return; end % Compile paths & initialize other variables: for g = 1:length(handles.name.GroupID) for s = 1:length(handles.name.SubjID{g}) for c = 1:length(handles.name.CondID) handles = CompilePaths(handles, g, s, c); try handles.gui.SelectComps{g}{s,c}; handles.gui.InpOutStatus{g}{s,c}; % Didn't check initialize in UpdateStatus. handles.gui.RmvCompStatus{g}{s,c}; % - More efficient for case-by-case basis. catch handles.gui.SelectComps{g}{s,c} = []; handles.gui.InpOutStatus{g}{s,c} = []; handles.gui.RmvCompStatus{g}{s,c} = []; end end end end % Update settings & GUI panels: handles = UpdateGroupIDSettings (handles); handles = UpdateSubjIDSettings (handles); handles = UpdateCondIDSettings (handles); % Detect & update status: for g = 1:length(handles.name.GroupID) StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ... handles.name.GroupID{g}], 'Windowstyle', 'modal'); for s = 1:length(handles.name.SubjID{g}) waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar); for c = 1:length(handles.name.CondID) handles = DetectStatus(handles, g, s, c); end end delete(StatusWaitbar) end handles = UpdateStatusSettings(handles); % Save handles: set(handles.TextboxDataID, 'String', handles.name.DataID); guidata(hObject, handles); % Remove ErrorLog if empty: if exist([pwd,'/ErrorLog_ICAcleaner.txt'], 'file') LogCheck = dir('ErrorLog_ICAcleaner.txt'); if LogCheck.bytes == 0 delete('ErrorLog_ICAcleaner.txt'); end end %--- Executes on button press in ButtonRedetectInputIDs. --% %----------------------------------------------------------% function ButtonRedetectInputIDs_Callback(hObject, eventdata, handles) % Reset settings & GUI panels: handles = ResetGroupIDSettings (handles); handles = ResetSubjIDSettings (handles); handles = ResetCondIDSettings (handles); handles = ResetStatusSettings (handles); handles.paths.InputPreprocMEG = []; handles.paths.ICAcomponents = []; handles.paths.ICAunmixing = []; handles.paths.ICAcleanData = []; handles.gui.SelectComps = []; % Compile Group, Subj, and CondIDs for DataID: % Note: Also initializes Group, Subj, CondIDs. handles = DetectGroupSubjCond(handles); if isempty(handles.name.GroupID) msgbox('ERROR: No GroupID folders detected for selected DataID.') return; end % Compile paths & initialize other variables: for g = 1:length(handles.name.GroupID) for s = 1:length(handles.name.SubjID{g}) for c = 1:length(handles.name.CondID) handles = CompilePaths(handles, g, s, c); try handles.gui.SelectComps{g}{s,c}; handles.gui.InpOutStatus{g}{s,c}; % Didn't check initialize in UpdateStatus. handles.gui.RmvCompStatus{g}{s,c}; % - More efficient for case-by-case basis. catch handles.gui.SelectComps{g}{s,c} = []; handles.gui.InpOutStatus{g}{s,c} = []; handles.gui.RmvCompStatus{g}{s,c} = []; end end end end % Update settings & GUI panels: handles = UpdateGroupIDSettings (handles); handles = UpdateSubjIDSettings (handles); handles = UpdateCondIDSettings (handles); % Detect & update status: for g = 1:length(handles.name.GroupID) StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ... handles.name.GroupID{g}], 'Windowstyle', 'modal'); for s = 1:length(handles.name.SubjID{g}) waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar); for c = 1:length(handles.name.CondID) handles = DetectStatus(handles, g, s, c); end end delete(StatusWaitbar) end handles = UpdateStatusSettings(handles); % Save handles: guidata(hObject, handles); % Remove ErrorLog if empty: if exist([pwd,'/ErrorLog_ICAcleaner.txt'], 'file') LogCheck = dir('ErrorLog_ICAcleaner.txt'); if LogCheck.bytes == 0 delete('ErrorLog_ICAcleaner.txt'); end end %--- Detect Group, Subj, and CondID's from DataID: ---% %-----------------------------------------------------% function OutputHandles = DetectGroupSubjCond(InputHandles) handles = InputHandles; % Reset params: handles.name.GroupID = []; handles.name.SubjID = []; handles.name.CondID = []; handles.paths.InputPreprocMEG = []; handles.paths.ICAcomponents = []; handles.paths.ICAunmixing = []; handles.paths.ICAcleanData = []; % Acquire GroupID folders within DataID: DetectedGroups = dir([handles.paths.DataID,'/GroupID_*']); RemoveIndex = []; for g = 1:length(DetectedGroups) DetectedGroups(g).name(1:8) = []; % Remove "GroupID_" prefix if DetectedGroups(g).isdir ~= 1 RemoveIndex = [RemoveIndex, g]; % Get unwanted indices end end DetectedGroups(RemoveIndex) = []; if isempty(DetectedGroups) handles.name.GroupID = []; else handles.name.GroupID = {DetectedGroups.name}; end % Scan PreprocInput .mat files for SubjID's and CondID's: CondIDs = []; for g = 1:length(handles.name.GroupID) GroupPath = [handles.paths.DataID,'/GroupID_',handles.name.GroupID{g}]; InputMats = dir([GroupPath,'/PreprocInputMEG_*.mat']); % Find InputMats for group InputMats = {InputMats.name}; SubjIDs = []; if ~isempty(InputMats) for m = 1:length(InputMats) LoadMat = load([GroupPath,'/',InputMats{m}]); SubjIDs = [SubjIDs; LoadMat.name.SubjID]; CondIDs = [CondIDs; cellstr(LoadMat.name.CurrentCondID)]; end else message = {['ERROR: PreprocInputMEG .mat file(s) missing for GroupID: ',... handles.name.GroupID{g}]; ''; ['As a result, some Subject & Condition IDs ' ... 'for the selected DataID may not be detected.']}; msgbox(message); end handles.name.SubjID{g} = unique(SubjIDs); end handles.name.CondID = unique(CondIDs); % Set output handles: OutputHandles = handles; %--- Compiles paths for selected indices: ---% %--------------------------------------------% function OutputHandles = CompilePaths(InputHandles, g, s, c) handles = InputHandles; handles.paths.InputPreprocMEG{g}{s,c} = ... [handles.paths.DataID,'/GroupID_',handles.name.GroupID{g},'/', ... handles.name.CondID{c},'/',handles.name.SubjID{g}{s},'_PreprocMEG.mat']; handles.paths.ICAunmixing{g}{s,c} = ... [handles.paths.DataID,'/GroupID_',handles.name.GroupID{g},'/', ... handles.name.CondID{c},'/',handles.name.SubjID{g}{s},'_ICAunmixing.mat']; handles.paths.ICAcomponents{g}{s,c} = ... [handles.paths.DataID,'/ICAcomps/GroupID_',handles.name.GroupID{g},'/', ... handles.name.CondID{c},'/',handles.name.SubjID{g}{s},'_ICAcomponents.mat']; handles.paths.ICAcleanData{g}{s,c} = ... [handles.paths.Rootpath,'/DataID-ICAclean_',handles.name.DataID, ... '/GroupID_',handles.name.GroupID{g},'/',handles.name.CondID{c},'/', ... handles.name.SubjID{g}{s},'_PreprocMEG.mat']; % Set output handles: OutputHandles = handles; %==========================================% % FUNCTIONS FOR ADDING OR REMOVING GROUPS: % %==========================================% %--- Executes on selection change in ListboxGroupID. ---% %-------------------------------------------------------% function ListboxGroupID_Callback(hObject, eventdata, handles) if isempty(handles.name.GroupID) return; end handles = UpdateSubjIDSettings (handles); handles = UpdateStatusSettings (handles); guidata(hObject, handles); %--- Executes on button press in ButtonRmvGroupID. ---% %-----------------------------------------------------% function ButtonRmvGroupID_Callback(hObject, eventdata, handles) if isempty(handles.name.GroupID) return; end if length(handles.name.GroupID) <= 1 msgbox('Note: Must have at least 1 GroupID.', 'Error:'); return; end SelectedIndex = get(handles.ListboxGroupID, 'Value'); handles.name.GroupID(SelectedIndex) = []; if ~isempty(handles.name.SubjID) handles.name.SubjID(SelectedIndex) = []; end if ~isempty(handles.paths.InputPreprocMEG) handles.paths.InputPreprocMEG (SelectedIndex) = []; handles.paths.ICAunmixing (SelectedIndex) = []; handles.paths.ICAcomponents (SelectedIndex) = []; handles.paths.ICAcleanData (SelectedIndex) = []; end if ~isempty(handles.gui.SelectComps) handles.gui.SelectComps(SelectedIndex) = []; end if ~isempty(handles.gui.InpOutStatus) handles.gui.InpOutStatus(SelectedIndex) = []; end if ~isempty(handles.gui.RmvCompStatus) handles.gui.RmvCompStatus(SelectedIndex) = []; end % Update settings & GUI: handles = UpdateGroupIDSettings (handles); handles = UpdateSubjIDSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); %--- Update GroupID settings & GUI panel: ---% %--------------------------------------------% function OutputHandles = UpdateGroupIDSettings(InputHandles) handles = InputHandles; % Update listbox: set(handles.ListboxGroupID, 'String', handles.name.GroupID); CurrentIndex = get(handles.ListboxGroupID, 'Value'); MaxGroupIndex = length(handles.name.GroupID); if isempty(CurrentIndex) || CurrentIndex == 0 || CurrentIndex > MaxGroupIndex set(handles.ListboxGroupID, 'Value', MaxGroupIndex); end % Set output handles: OutputHandles = handles; %--- Reset GroupID settings & GUI panel: ---% %-------------------------------------------% function OutputHandles = ResetGroupIDSettings(InputHandles) handles = InputHandles; handles.name.GroupID = []; set(handles.ListboxGroupID, 'String', []); set(handles.ListboxGroupID, 'Value', 1); % Set output handles: OutputHandles = handles; %============================================% % FUNCTIONS FOR ADDING OR REMOVING SUBJECTS: % %============================================% %--- Executes on selection change in ListboxSubjID. ---% %------------------------------------------------------% function ListboxSubjID_Callback(hObject, eventdata, handles) if isempty(handles.name.SubjID) return; end GroupIndex = get(handles.ListboxGroupID, 'Value'); if isempty(handles.name.SubjID{GroupIndex}) return; end SubjIndex = get(handles.ListboxSubjID, 'Value'); set(handles.ListboxInpOutStatus, 'Value', SubjIndex); set(handles.ListboxRmvCompStatus, 'Value', SubjIndex); %--- User enters subject to add into this textbox. ---% %-----------------------------------------------------% function TextboxSubjID_Callback(hObject, eventdata, handles) keypress = get(gcf,'CurrentCharacter'); if isequal(keypress, char(13)) ButtonAddSubjID_Callback(hObject, eventdata, handles); end %--- Executes on button press in ButtonAddSubjID. ---% %----------------------------------------------------% function ButtonAddSubjID_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) msgbox('Warning: Load DataID first.', 'Warning:'); return; end if isempty(handles.name.GroupID) msgbox('Error: No GroupIDs specified.', 'Error:'); return; end % Read entered SubjID: InputSubjID = get(handles.TextboxSubjID, 'String'); InputSubjID = deblank(InputSubjID); InputSubjID = regexprep(InputSubjID, '\s+', '_'); InputSubjID = cellstr(InputSubjID); if isempty(InputSubjID{1}) return; end GroupIndex = get(handles.ListboxGroupID, 'Value'); if ismember(InputSubjID{1}, handles.name.SubjID{GroupIndex}) return; % If SubjID already added end % Add SubjID for group & initialize: handles.name.SubjID{GroupIndex} = [handles.name.SubjID{GroupIndex}; InputSubjID]; NewSubjIndex = length(handles.name.SubjID{GroupIndex}); for c = 1:length(handles.name.CondID) handles.gui.SelectComps{GroupIndex}{NewSubjIndex,c} = []; handles = CompilePaths(handles, GroupIndex, NewSubjIndex, c); handles = DetectStatus(handles, GroupIndex, NewSubjIndex, c); end % Update settings & GUI: handles = UpdateSubjIDSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: set(handles.ListboxSubjID, 'Value', NewSubjIndex); if ~isempty(handles.gui.InpOutStatus) set(handles.ListboxInpOutStatus, 'Value', NewSubjIndex); end if ~isempty(handles.gui.RmvCompStatus) set(handles.ListboxRmvCompStatus, 'Value', NewSubjIndex); end guidata(hObject, handles); %--- Executes on button press in ButtonRmvSubjID. ---% %----------------------------------------------------% function ButtonRmvSubjID_Callback(hObject, eventdata, handles) if isempty(handles.name.SubjID) return; end GroupIndex = get(handles.ListboxGroupID, 'Value'); SubjIndex = get(handles.ListboxSubjID, 'Value'); if isempty(handles.name.SubjID{GroupIndex}) return; end handles.name.SubjID{GroupIndex}(SubjIndex) = []; if ~isempty(handles.paths.InputPreprocMEG) handles.paths.InputPreprocMEG {GroupIndex}(SubjIndex,:) = []; handles.paths.ICAunmixing {GroupIndex}(SubjIndex,:) = []; handles.paths.ICAcomponents {GroupIndex}(SubjIndex,:) = []; handles.paths.ICAcleanData {GroupIndex}(SubjIndex,:) = []; end if ~isempty(handles.gui.SelectComps) handles.gui.SelectComps{GroupIndex}(SubjIndex,:) = []; end if ~isempty(handles.gui.InpOutStatus) handles.gui.InpOutStatus{GroupIndex}(SubjIndex,:) = []; end if ~isempty(handles.gui.RmvCompStatus) handles.gui.RmvCompStatus{GroupIndex}(SubjIndex,:) = []; end % Update settings & GUI: handles = UpdateSubjIDSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); %--- Update SubjID settings & GUI panel: ---% %-------------------------------------------% function OutputHandles = UpdateSubjIDSettings(InputHandles) handles = InputHandles; % Update listbox: GroupIndex = get(handles.ListboxGroupID, 'Value'); if isempty(handles.name.SubjID) set(handles.ListboxSubjID, 'String', []); MaxSubjIndex = 0; else set(handles.ListboxSubjID, 'String', handles.name.SubjID{GroupIndex}); MaxSubjIndex = length(handles.name.SubjID{GroupIndex}); end SubjIndex = get(handles.ListboxSubjID, 'Value'); if isempty(SubjIndex) || SubjIndex == 0 || SubjIndex > MaxSubjIndex set(handles.ListboxSubjID, 'Value', MaxSubjIndex); if ~isempty(handles.gui.InpOutStatus) set(handles.ListboxInpOutStatus, 'Value', MaxSubjIndex); end if ~isempty(handles.gui.RmvCompStatus) set(handles.ListboxRmvCompStatus, 'Value', MaxSubjIndex); end end % Set output handles: OutputHandles = handles; %--- Reset SubjID settings & GUI panel: ---% %------------------------------------------% function OutputHandles = ResetSubjIDSettings(InputHandles) handles = InputHandles; handles.name.SubjID = []; set(handles.ListboxSubjID, 'String', []); set(handles.ListboxSubjID, 'Value', 1); % Set output handles: OutputHandles = handles; %==============================================% % FUNCTIONS FOR ADDING OR REMOVING CONDITIONS: % %==============================================% %--- Executes on selection change in ListboxCondID. ---% %------------------------------------------------------% function ListboxCondID_Callback(hObject, eventdata, handles) if isempty(handles.name.CondID) return; end handles = UpdateStatusSettings(handles); guidata(hObject, handles); %--- User enters condition to add into this textbox. ---% %-------------------------------------------------------% function TextboxCondID_Callback(hObject, eventdata, handles) keypress = get(gcf,'CurrentCharacter'); if isequal(keypress, char(13)) ButtonAddCondID_Callback(hObject, eventdata, handles); end %--- Executes on button press in ButtonAddCondID. ---% %----------------------------------------------------% function ButtonAddCondID_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) msgbox('Warning: Load DataID first.', 'Warning:'); return; end if isempty(handles.name.GroupID) msgbox('Error: No GroupIDs specified.', 'Error:'); return; end % Read entered CondID: InputCondID = get(handles.TextboxCondID, 'String'); InputCondID = deblank(InputCondID); InputCondID = regexprep(InputCondID, '\s+', '_'); InputCondID = cellstr(InputCondID); if isempty(InputCondID{1}) return; end if ismember(InputCondID{1}, handles.name.CondID) return; % If CondID already added end % Add CondID and initialize: handles.name.CondID = [handles.name.CondID; InputCondID]; NewCondIndex = length(handles.name.CondID); for g = 1:length(handles.name.GroupID) if isempty(handles.name.SubjID) continue; end for s = 1:length(handles.name.SubjID{g}) handles.gui.SelectComps{g}{s, NewCondIndex} = []; handles = CompilePaths(handles, g, s, NewCondIndex); handles = DetectStatus(handles, g, s, NewCondIndex); end end set(handles.ListboxCondID, 'Value', NewCondIndex); % Update settings & GUI: handles = UpdateCondIDSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); %--- Executes on button press in ButtonRmvCondID. ---% %----------------------------------------------------% function ButtonRmvCondID_Callback(hObject, eventdata, handles) if isempty(handles.name.CondID) return; end SelectedIndex = get(handles.ListboxCondID, 'Value'); handles.name.CondID(SelectedIndex) = []; for g = 1:length(handles.name.GroupID) if ~isempty(handles.paths.InputPreprocMEG) handles.paths.InputPreprocMEG {g}(:,SelectedIndex) = []; handles.paths.ICAunmixing {g}(:,SelectedIndex) = []; handles.paths.ICAcomponents {g}(:,SelectedIndex) = []; handles.paths.ICAcleanData {g}(:,SelectedIndex) = []; end if ~isempty(handles.gui.SelectComps) handles.gui.SelectComps{g}(:,SelectedIndex) = []; end if ~isempty(handles.gui.InpOutStatus) handles.gui.InpOutStatus{g}(:,SelectedIndex) = []; end if ~isempty(handles.gui.RmvCompStatus) handles.gui.RmvCompStatus{g}(:,SelectedIndex) = []; end end % Update settings & GUI: handles = UpdateCondIDSettings (handles); handles = UpdateStatusSettings (handles); % Save handles: guidata(hObject, handles); %--- Updates CondID settings & GUI panel: ---% %--------------------------------------------% function OutputHandles = UpdateCondIDSettings(InputHandles) handles = InputHandles; % Update listbox: set(handles.ListboxCondID, 'String', handles.name.CondID); CurrentIndex = get(handles.ListboxCondID, 'Value'); MaxCondIndex = length(handles.name.CondID); if isempty(CurrentIndex) || CurrentIndex == 0 || CurrentIndex > MaxCondIndex set(handles.ListboxCondID, 'Value', MaxCondIndex); end % Set output handles: OutputHandles = handles; %--- Reset CondID settings & GUI panel: ---% %------------------------------------------% function OutputHandles = ResetCondIDSettings(InputHandles) handles = InputHandles; handles.name.CondID = []; set(handles.ListboxCondID, 'String', []); set(handles.ListboxCondID, 'Value', 1); % Set output handles: OutputHandles = handles; %===============================% % FUNCTIONS FOR STATUS UPDATES: % %===============================% %--- Executes on selection change in ListboxInpOutStatus. ---% %------------------------------------------------------------% function ListboxInpOutStatus_Callback(hObject, eventdata, handles) if isempty(handles.gui.InpOutStatus) return; end if ~isempty(handles.name.GroupID) % In case where SubjID exist but CondID missing GroupIndex = get(handles.ListboxGroupID, 'Value'); if isempty(handles.gui.InpOutStatus{GroupIndex}) return; end end SelectedIndex = get(handles.ListboxInpOutStatus, 'Value'); set(handles.ListboxSubjID, 'Value', SelectedIndex); set(handles.ListboxRmvCompStatus, 'Value', SelectedIndex); %--- Executes on selection change in ListboxRmvCompStatus. ---% %-------------------------------------------------------------% function ListboxRmvCompStatus_Callback(hObject, eventdata, handles) if isempty(handles.gui.RmvCompStatus) return; end if ~isempty(handles.name.GroupID) GroupIndex = get(handles.ListboxGroupID, 'Value'); if isempty(handles.gui.RmvCompStatus{GroupIndex}) return; end end SelectedIndex = get(handles.ListboxRmvCompStatus, 'Value'); set(handles.ListboxSubjID, 'Value', SelectedIndex); set(handles.ListboxInpOutStatus, 'Value', SelectedIndex); %--- Executes on button press in ButtonRefreshStatus. ---% %--------------------------------------------------------% function ButtonRefreshStatus_Callback(hObject, eventdata, handles) % Detect & update status: for g = 1:length(handles.name.GroupID) StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ... handles.name.GroupID{g}], 'Windowstyle', 'modal'); for s = 1:length(handles.name.SubjID{g}) waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar); for c = 1:length(handles.name.CondID) handles = DetectStatus(handles, g, s, c); end end delete(StatusWaitbar) end handles = UpdateStatusSettings(handles); % Save handles: guidata(hObject, handles); %--- Executes on button press in CheckboxShowOutputStatus. ---% %-------------------------------------------------------------% function CheckboxShowOutputStatus_Callback(hObject, eventdata, handles) % Detect & update status: for g = 1:length(handles.name.GroupID) StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ... handles.name.GroupID{g}], 'Windowstyle', 'modal'); for s = 1:length(handles.name.SubjID{g}) waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar); for c = 1:length(handles.name.CondID) handles = DetectStatus(handles, g, s, c); end end delete(StatusWaitbar) end handles = UpdateStatusSettings(handles); % Save handles: guidata(hObject, handles); %--- Detect input file status: ---% %---------------------------------% function OutputHandles = DetectStatus(InputHandles, g, s, c) handles = InputHandles; InputPreprocMEG = handles.paths.InputPreprocMEG{g}{s,c}; ICAunmixing = handles.paths.ICAunmixing{g}{s,c}; ICAcomponents = handles.paths.ICAcomponents{g}{s,c}; ICAcleanData = handles.paths.ICAcleanData{g}{s,c}; % Get input or output file status: if ~exist(ICAcleanData, 'file') || get(handles.CheckboxShowOutputStatus, 'Value') == 0 if exist(InputPreprocMEG, 'file') if exist(ICAcomponents, 'file') StatusMsg = 'Input PreprocMEG found (ICA components found).'; elseif exist(ICAunmixing, 'file') StatusMsg = 'Input PreprocMEG found (Unmixing data found; Run ICA to apply).'; else StatusMsg = 'Input PreprocMEG found (Ready for ICA).'; end else StatusMsg = 'Error: Input PreprocMEG file missing.'; end else LoadCleanData = LoadFTmat(ICAcleanData, 'ICAcleaner'); if isempty(LoadCleanData) StatusMsg = 'Error: Output file contains errors. See ErrorLog.'; else if isfield(LoadCleanData, 'ICAcompRemoved') if isempty(LoadCleanData.ICAcompRemoved) StatusMsg = 'ICA cleaned file found: No components removed.'; else NumCompRmv = num2str(length(LoadCleanData.ICAcompRemoved)); StrCompRmv = regexprep(num2str(LoadCleanData.ICAcompRemoved), '\s+', ', '); StatusMsg = ['ICA cleaned file found: ', ... NumCompRmv,' comp. removed (',StrCompRmv,')']; end else StatusMsg = 'Error: Output file is missing ICAcompRemoved field.'; end end end handles.gui.InpOutStatus{g}{s,c} = StatusMsg; % Get ICA component status: if ~exist(ICAunmixing, 'file') RmvCompStatus = 'Missing ICA decomposition files (Run ICA).'; else if isempty(handles.gui.SelectComps{g}{s,c}) RmvCompStatus = 'Select unwanted components.'; else StrCompRmv = regexprep(num2str(handles.gui.SelectComps{g}{s,c}), '\s+', ', '); RmvCompStatus = ['Rejecting components: [',StrCompRmv,']']; end end handles.gui.RmvCompStatus{g}{s,c} = RmvCompStatus; % Set output handles: OutputHandles = handles; %--- Update status settings & GUI panel: ---% %-------------------------------------------% function OutputHandles = UpdateStatusSettings(InputHandles) handles = InputHandles; % Make sure cells initialized: for g = 1:length(handles.name.GroupID) for s = 1:length(handles.name.SubjID{g}) for c = 1:length(handles.name.CondID) try handles.gui.SelectComps{g}{s,c}; handles.gui.InpOutStatus{g}{s,c}; % Check just in case. handles.gui.RmvCompStatus{g}{s,c}; % - ** If too much delay, can rmv. catch handles.gui.SelectComps{g}{s,c} = []; handles.gui.InpOutStatus{g}{s,c} = []; handles.gui.RmvCompStatus{g}{s,c} = []; end end end end % Update listbox: GroupIndex = get(handles.ListboxGroupID, 'Value'); SubjIndex = get(handles.ListboxSubjID, 'Value'); CondIndex = get(handles.ListboxCondID, 'Value'); if isempty(handles.gui.InpOutStatus) || isempty(handles.gui.InpOutStatus{GroupIndex}) set(handles.ListboxInpOutStatus, 'String', []); set(handles.ListboxInpOutStatus, 'Value', 1); else set(handles.ListboxInpOutStatus, 'String', ... handles.gui.InpOutStatus{GroupIndex}(:,CondIndex)); if get(handles.ListboxInpOutStatus, 'Value') ~= SubjIndex set(handles.ListboxInpOutStatus, 'Value', SubjIndex); end end if isempty(handles.gui.RmvCompStatus) || isempty(handles.gui.RmvCompStatus{GroupIndex}) set(handles.ListboxRmvCompStatus, 'String', []); set(handles.ListboxRmvCompStatus, 'Value', 1); else set(handles.ListboxRmvCompStatus, 'String', ... handles.gui.RmvCompStatus{GroupIndex}(:,CondIndex)); if get(handles.ListboxRmvCompStatus, 'Value') ~= SubjIndex set(handles.ListboxRmvCompStatus, 'Value', SubjIndex) end end % Set output handles: OutputHandles = handles; %--- Reset status settings & GUI panel: ---% %------------------------------------------% function OutputHandles = ResetStatusSettings(InputHandles) handles = InputHandles; % Reset: handles.gui.InpOutStatus = []; handles.gui.RmvCompStatus = []; % Reinitialize: for g = 1:length(handles.name.GroupID) for s = 1:length(handles.name.SubjID{g}) for c = 1:length(handles.name.CondID) handles.gui.InpOutStatus{g}{s,c} = []; handles.gui.RmvCompStatus{g}{s,c} = []; end end end % Reset GUI listboxes: set(handles.ListboxInpOutStatus, 'String', []); set(handles.ListboxRmvCompStatus, 'String', []); set(handles.ListboxInpOutStatus, 'Value', 1); set(handles.ListboxRmvCompStatus, 'Value', 1); % Set output handles: OutputHandles = handles; %=======================% % FUNCTIONS TO RUN ICA: % %=======================% %--- Executes on button press in ButtonShowInstructions. ---% %-----------------------------------------------------------% function ButtonShowInstructions_Callback(hObject, eventdata, handles) Instructions = {'-------------'; 'INSTRUCTIONS:'; '-------------'; ''; 'LOADING INPUT DATA:'; ' 1) Load the DataID that you wish to apply ICA cleaning to.'; ' 2) The DataID will be scanned for Group, Subject & Condition IDs.'; ' 3) Use the "-" keys to exclude datasets from the ICA analysis.'; ' 4) Use the "+" keys to add missing Subject or Condition IDs.'; ''; ' NOTE: To restore the full list of Group, Subject, and Condition IDs'; ' found within the DataID, push the "Redetect Input" button.'; ''; ''; 'RUN ICA DECOMPOSITION:'; ' 1) Change ICA settings as needed using the "ICA Adv. Settings" button.'; ' 2) Once desired data is selected (see above), push "Run ICA" button.'; ''; ''; 'VIEWING ICA COMPONENT RESULTS:'; ' - Select the Group, Subj & Cond ID you wish to view from the lists.'; ' - Push the "View Components" button to open the component browser.'; ' This browser displays topoplots & time-courses for each component.'; ' Note: Time-courses display concatenated trial data for components.'; ''; ' - Using the Data Browser:'; ' a) To change components viewed, use the ">" & "<" keys for "Channels".'; ' b) To scroll across time-course, use the ">" & "<" keys for "Segment".'; ' c) To change amp. scaling, use the ">" & "<" keys under "Vertical".'; ' d) To change time scaling, use the ">" & "<" keys under "Horizontal".'; ''; ''; 'REJECTING COMPONENTS:'; ' 1) Select the Group, Subj & Cond ID you wish to view from the lists.'; ' 2) Identify artifact components for the selected dataset (see above).'; ' 3) Push the "Select Components" button and select artifact components.'; ' 4) Repeat Steps 1-3 for each dataset.'; ' 5) When ready, push the "Rmv Comp. & Clean Data" button.'; ''; ''}; msgbox(Instructions, 'INSTRUCTIONS:') %--- Executes on button press in ButtonAdvSettings. ---% %------------------------------------------------------% function ButtonAdvSettings_Callback(hObject, eventdata, handles) if isempty(handles.paths.Rootpath) msgbox('Warning: Select target directory first.', 'Warning:'); return; end if isempty(handles.name.DataID) msgbox('Warning: Load DataID first.', 'Warning:'); return; end open([handles.paths.DataID,'/SETTINGS/Settings_ICA.m']); %--- Executes on button press in ButtonRunICA. ---% %-------------------------------------------------% function ButtonRunICA_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) msgbox('Warning: Load DataID first.', 'Warning:'); return; end if isempty(handles.name.GroupID) msgbox('Error: No GroupIDs specified.', 'Error:'); return; end if isempty(handles.name.SubjID) msgbox('Error: No SubjIDs specified.', 'Error:'); return; else for g = 1:length(handles.name.GroupID) if isempty(handles.name.SubjID{g}) msgbox('Error: Not all Groups have SubjIDs added.', 'Error:') return; end end end if isempty(handles.name.CondID) msgbox('Error: No CondIDs specified.', 'Error:'); return; end % Load required parameters: InputParams.name = handles.name; InputParams.paths.InputPreprocMEG = handles.paths.InputPreprocMEG; InputParams.paths.ICAunmixing = handles.paths.ICAunmixing; InputParams.paths.ICAcomponents = handles.paths.ICAcomponents; FTcfg.ResampleICA = []; FTcfg.ICA = []; CurrentDir = pwd; cd([handles.paths.DataID,'/SETTINGS/']); [FTcfg.ResampleICA, FTcfg.ICA] = Settings_ICA; cd(CurrentDir); % Check for previously computed unmixing matrices: ExistingFiles = 0; for g = 1:length(handles.name.GroupID) for s = 1:length(handles.name.SubjID{g}) for c = 1:length(handles.name.CondID) if exist(handles.paths.ICAunmixing{g}{s,c}, 'file') ExistingFiles = 1; end end end end if ExistingFiles == 1 prompt = {'CONFIRM: ICA unmixing matrices from previous ICA runs detected.'; ''; 'To APPLY existing unmixing data to their respective datasets, push APPLY.'; 'Note: Choose this option to save time if ICA settings have NOT changed.'; ''; 'To REDO & OVERWRITE the ICA decomposition for each dataset, push REDO.'; 'Note: Choose this option if you wish to re-run ICA with new settings.'}; RunChoice = questdlg(prompt, 'NOTE:', 'APPLY', 'REDO', 'Cancel', 'Cancel'); else RunChoice = 'REDO'; end if strcmp(RunChoice, 'Cancel') return; end CheckOpenPCT % Run ICA decomposition: disp('PERFORMING ICA DECOMPOSITION:') MEGpipeline_RunICA(FTcfg, InputParams, RunChoice); % Detect & update status: for g = 1:length(handles.name.GroupID) StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ... handles.name.GroupID{g}], 'Windowstyle', 'modal'); for s = 1:length(handles.name.SubjID{g}) waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar); for c = 1:length(handles.name.CondID) handles = DetectStatus(handles, g, s, c); end end delete(StatusWaitbar); end handles = UpdateStatusSettings(handles); % Save handles: guidata(hObject, handles); % Remove ErrorLog if empty: if exist([pwd,'/ErrorLog_ICAcleaner.txt'], 'file') LogCheck = dir('ErrorLog_ICAcleaner.txt'); if LogCheck.bytes == 0 delete('ErrorLog_ICAcleaner.txt'); end end %========================================% % FUNCTIONS TO VIEW & REJECT COMPONENTS: % %========================================% %--- Executes on button press in ButtonViewComponents. ---% %---------------------------------------------------------% function ButtonViewComponents_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) msgbox('Warning: Load DataID first.', 'Warning:'); return; end if isempty(handles.name.GroupID) msgbox('Error: No GroupIDs specified.', 'Error:'); return; end if isempty(handles.name.SubjID) msgbox('Error: No SubjIDs specified.', 'Error:'); return; else g = get(handles.ListboxGroupID, 'Value'); if isempty(handles.name.SubjID{g}) msgbox('Error: No SubjIDs added for selected Group.', 'Error:') return; end end if isempty(handles.name.CondID) msgbox('Error: No CondIDs specified.', 'Error:'); return; end % Load component file for dataset: % Note: Didn't read from disk (need sensor layout). g = get(handles.ListboxGroupID, 'Value'); s = get(handles.ListboxSubjID, 'Value'); c = get(handles.ListboxCondID, 'Value'); if ~exist(handles.paths.ICAcomponents{g}{s,c}, 'file') msgbox('Error: ICA component file missing for selected dataset.') return; end LoadComp = LoadFTmat(handles.paths.ICAcomponents{g}{s,c}, 'ICAcleaner'); if isempty(LoadComp) msgbox('Error: ICA component file found, but contains errors. See ErrorLog.') return; end % Open databrowser: cfgview.viewmode = 'component'; cfgview.channel = [1:10]; % View 10 components at a time. cfgview.compscale = 'local'; % Keep this local for proper scaling. cfgview.zlim = 'maxmin'; cfgview.ylim = 'maxmin'; cfgview.continuous = 'yes'; % Concatenate trials for viewing. cfgview.blocksize = 20; ft_databrowser(cfgview, LoadComp); % Also open topoplots for first 30 components: ** Removed for now, takes too long % figure; % Open new figure. % cfgtopo.component = [1:20]; % cfgtopo.comment = 'no'; % ft_topoplotIC(cfgtopo, LoadComp); % Save handles: guidata(hObject, handles); %--- Executes on button press in ButtonSelectComponents. ---% %------------------------------------------------------------ function ButtonSelectComponents_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) msgbox('Warning: Load DataID first.', 'Warning:'); return; end if isempty(handles.name.GroupID) msgbox('Error: No GroupIDs specified.', 'Error:'); return; end if isempty(handles.name.SubjID) msgbox('Error: No SubjIDs specified.', 'Error:'); return; else g = get(handles.ListboxGroupID, 'Value'); if isempty(handles.name.SubjID{g}) msgbox('Error: No SubjIDs added for selected Group.', 'Error:') return; end end if isempty(handles.name.CondID) msgbox('Error: No CondIDs specified.', 'Error:'); return; end % Load unmixing info for dataset: % Note: Only need unmixing info for component rejection. % Allows user to apply previous ICA cleaning to a dataset. g = get(handles.ListboxGroupID, 'Value'); s = get(handles.ListboxSubjID, 'Value'); c = get(handles.ListboxCondID, 'Value'); if ~exist(handles.paths.ICAunmixing{g}{s,c}, 'file') message = {'ERROR:'; 'ICA unmixing info is missing for the selected dataset.'; 'Run ICA for the dataset to generate required files.'}; msgbox(message); return; end LoadUnmix = LoadFTmat(handles.paths.ICAunmixing{g}{s,c}, 'ICAcleaner'); if isempty(LoadUnmix) msgbox('Error: ICA unmixing file contains errors. See ErrorLog.') return; end % Open selection list for available components: SelectedComps = listdlg('PromptString', 'Select ICA components to REJECT:', ... 'ListSize', [300, 300], 'SelectionMode', 'multiple', 'ListString', LoadUnmix.label); handles.gui.SelectComps{g}{s,c} = SelectedComps; % Detect & update status: handles = DetectStatus(handles, g, s, c); handles = UpdateStatusSettings(handles); % Save handles: guidata(hObject, handles); %--- Executes on button press in ButtonRmvCompCleanData. ---% %-----------------------------------------------------------% function ButtonRmvCompCleanData_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) msgbox('Warning: Load DataID first.', 'Warning:'); return; end if isempty(handles.name.GroupID) msgbox('Error: No GroupIDs specified.', 'Error:'); return; end if isempty(handles.name.SubjID) msgbox('Error: No SubjIDs specified.', 'Error:'); return; else for g = 1:length(handles.name.GroupID) if isempty(handles.name.SubjID{g}) msgbox('Error: Not all Groups have SubjIDs added.', 'Error:') return; end end end if isempty(handles.name.CondID) msgbox('Error: No CondIDs specified.', 'Error:'); return; end % Load required parameters: InputParams.name = handles.name; InputParams.paths.InputPreprocMEG = handles.paths.InputPreprocMEG; InputParams.paths.ICAunmixing = handles.paths.ICAunmixing; InputParams.paths.ICAcleanData = handles.paths.ICAcleanData; InputParams.RejectComps = handles.gui.SelectComps; % Check if unmixing info generated for each dataset: % Check if components selected for each dataset: MissingUnmixing = 0; MissingSelection = 0; for g = 1:length(handles.name.GroupID) for s = 1:length(handles.name.SubjID{g}) for c = 1:length(handles.name.CondID) if ~exist(handles.paths.ICAunmixing{g}{s,c}, 'file') MissingUnmixing = 1; end if isempty(handles.gui.SelectComps{g}{s,c}) MissingSelection = 1; end end end end if MissingUnmixing == 1 message = {'ERROR:'; ''; 'ICA unmixing info is missing for some of the selected datasets.'; 'Run ICA to generate the required files for these datasets.'}; msgbox(message, 'ERROR:') return; end if MissingSelection == 1 prompt = {'WARNING:'; ''; 'Some of the input datasets do NOT have components selected for removal.'; 'Are you sure you wish to leave these datasets UNALTERED?'; ''; 'IMPORTANT: If you continue, components will NOT be removed from'; 'the datasets in question. They will simply be copied into the output'; 'DataID-ICAclean folder.'}; ContChoice = questdlg(prompt, 'WARNING:', 'CONTINUE', 'CANCEL', 'CANCEL'); if strcmp(ContChoice, 'CANCEL') return; end end CheckOpenPCT % Reject components and reconstruct data: disp('REJECTING COMPONENTS & RECONSTRUCTING DATA:') MEGpipeline_RemoveICAcomps(InputParams); % Detect & update status: for g = 1:length(handles.name.GroupID) StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ... handles.name.GroupID{g}], 'Windowstyle', 'modal'); for s = 1:length(handles.name.SubjID{g}) waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar); for c = 1:length(handles.name.CondID) handles = DetectStatus(handles, g, s, c); end end delete(StatusWaitbar) end handles = UpdateStatusSettings(handles); % Make copy of PreprocSettings .mat in new DataID folder: PathOrigDataID = handles.paths.DataID; PathCleanDataID = [handles.paths.Rootpath,'/DataID-ICAclean_',handles.name.DataID]; OldSettingsFile = [PathOrigDataID,'/PreprocSettings.mat']; NewSettingsFile = [PathCleanDataID,'/PreprocSettings.mat']; if exist(OldSettingsFile, 'file') if exist(NewSettingsFile, 'file') delete(NewSettingsFile); end CopyStatus = copyfile(OldSettingsFile, NewSettingsFile, 'f'); if CopyStatus == 0 msgbox('Warning: Failed to copy PreprocSettings.mat to new DataID-ICAclean folder.') end end % Make copy of PreprocInputMEG .mat files in new DataID folder: CopyFailed = 0; for g = 1:length(handles.name.GroupID) GroupPath = [handles.paths.DataID,'/GroupID_',handles.name.GroupID{g}]; InputMats = dir([GroupPath,'/PreprocInputMEG_*.mat']); % Find InputMats for group InputMats = {InputMats.name}; for m = 1:length(InputMats) OldMatFile = [PathOrigDataID,'/GroupID_',handles.name.GroupID{g},'/',InputMats{m}]; NewMatFile = [PathCleanDataID,'/GroupID_',handles.name.GroupID{g},'/',InputMats{m}]; if exist(NewMatFile, 'file') delete(NewMatFile); end CopyStatus = copyfile(OldMatFile, NewMatFile, 'f'); if CopyStatus == 0 CopyFailed = 1; end end end if CopyFailed == 1 msgbox('Warning: Failed to copy PreprocInputMEG .mat(s) to new DataID-ICAclean folder.') end % Ask user if they wish to remove component files: ButtonDeleteCompFiles_Callback(hObject, eventdata, handles); % Save handles: guidata(hObject, handles); % Remove ErrorLog if empty: if exist([pwd,'/ErrorLog_ICAcleaner.txt'], 'file') LogCheck = dir('ErrorLog_ICAcleaner.txt'); if LogCheck.bytes == 0 delete('ErrorLog_ICAcleaner.txt'); end end %--- Executes on button press in ButtonDeleteCompFiles. ---% %----------------------------------------------------------% function ButtonDeleteCompFiles_Callback(hObject, eventdata, handles) if isempty(handles.name.DataID) msgbox('Warning: Load DataID first.', 'Warning:'); return; end if isempty(handles.name.GroupID) msgbox('Error: No GroupIDs specified.', 'Error:'); return; end if isempty(handles.name.SubjID) msgbox('Error: No SubjIDs specified.', 'Error:'); return; else for g = 1:length(handles.name.GroupID) if isempty(handles.name.SubjID{g}) msgbox('Error: Not all Groups have SubjIDs added.', 'Error:') return; end end end if isempty(handles.name.CondID) msgbox('Error: No CondIDs specified.', 'Error:'); return; end % Confirm removal: prompt = {'RECOMMENDED:'; ''; 'To save space, ICA component files can be removed after ICA cleaning.'; 'Do you wish to remove these large component files?'; ''; 'NOTE: Unmixing info from the ICA decompositions will be kept.'; 'These will allow you to quickly create component files again if needed.'}; RmvCompFiles = questdlg(prompt, 'RECOMMENDED:', 'YES', 'NO', 'YES'); if strcmp(RmvCompFiles, 'NO') return; end % Check if ICAcleanData exists for all datasets: UnfinishedCleaning = 0; for g = 1:length(handles.name.GroupID) for s = 1:length(handles.name.SubjID{g}) for c = 1:length(handles.name.CondID) ICAcomponents = handles.paths.ICAcomponents{g}{s,c}; ICAcleanData = handles.paths.ICAcleanData{g}{s,c}; if exist(ICAcomponents, 'file') && ~exist(ICAcleanData, 'file') UnfinishedCleaning = 1; end end end end if UnfinishedCleaning == 1 prompt = {'WARNING:'; ''; 'Some of the selected datasets have NOT been ICA cleaned yet.'; 'Are you sure you wish to remove component files?'}; ContinueRmv = questdlg(prompt, 'WARNING:', 'YES', 'NO', 'NO'); if strcmp(ContinueRmv, 'NO') return; end end % Remove component files: for g = 1:length(handles.name.GroupID) for s = 1:length(handles.name.SubjID{g}) for c = 1:length(handles.name.CondID) if exist(handles.paths.ICAcomponents{g}{s,c}, 'file') delete(handles.paths.ICAcomponents{g}{s,c}); end end end end %=================================% % FUNCTION TO OPEN MODAL WAITBOX: % %=================================% function WaitBox = StartWaitBox(TextString) WaitBox = dialog('Units', 'pixels', 'Position', [500 500 300 40],... 'Windowstyle', 'modal', 'NextPlot', 'new', 'Name', 'Please Wait:'); uicontrol('Parent', WaitBox, 'Units', 'pixels', 'Position', [20 10 250 20],... 'Style', 'text', 'String', TextString, 'FontWeight', 'bold'); movegui(WaitBox, 'center'); %============================% % GUIDE CREATEFCN FUNCTIONS: % %============================% % --- Executes during object creation, after setting all properties. function TextboxRootpath_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxDataID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxGroupID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxSubjID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxSubjID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxCondID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxCondID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxInpOutStatus_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxRmvCompStatus_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end